/*********************************************************************************
 *      Copyright:  (C) 2022 Nikel
 *                  All rights reserved.
 *
 *       Filename:  mosquitto.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(28/04/22)
 *         Author:  zhouyanlin <www.zhouyanlin1222@qq.com>
 *      ChangeLog:  1, Release initial version on "28/04/22 10:53:04"
 *                 
 ********************************************************************************/

#include "msqt.h"

//#define MQTT_DBG_PRINTF

#ifdef MQTT_DBG_PRINTF
#define mqtt_printf(format,args...) mqtt_printf(format, ##args)
#else
#define mqtt_printf(format,args...) do{} while(0)
#endif

int mosquitto_init(mqtt_ctx_t *mqtt_ctx)
{
    //libmosquitto 库初始化
    if( mosquitto_lib_init() != MOSQ_ERR_SUCCESS)
    {
        mqtt_printf("mosquitto_init failure!\n");
        return -1;
    }
    mqtt_printf ("mosquitto_lib_init successful\n");

    //创建mosquitto客户端
    mqtt_ctx->mosq = mosquitto_new(mqtt_ctx->clientid, true, NULL);
    if(!mqtt_ctx->mosq)
    {
        mqtt_printf("create client failed..\n");
        mosquitto_lib_cleanup();
        return -2;
    }
    mqtt_printf ("mosquitto_new successful!\n");

#if 0
     //设置回调函数
    mosquitto_log_callback_set(mqtt_ctx->mosq, my_log_callback);
    mosquitto_connect_callback_set(mqtt_ctx->mosq, my_connect_callback);
    mosquitto_subscribe_callback_set(mqtt_ctx->mosq, on_subscribe);
    mosquitto_message_callback_set(mqtt_ctx->mosq, on_message);
	mosquitto_disconnect_callback_set(mqtt_ctx->mosq, on_disconnect);
    mosquitto_publish_callback_set(mqtt_ctx->mosq, on_publish);

#endif

    //设置用户名密码
    if( mosquitto_username_pw_set(mqtt_ctx->mosq, mqtt_ctx->username, mqtt_ctx->passward) != MOSQ_ERR_SUCCESS )
    {
        mqtt_printf ("mosquitto_username_pw_set failure\n");
        return -3;
    }
    mqtt_printf ("mosquitto_username_pw_set successful!\n");

#if 1
	//连接服务器
	if(mosquitto_connect(mqtt_ctx->mosq, mqtt_ctx->host, mqtt_ctx->port, 60) != MOSQ_ERR_SUCCESS)
    {
        mqtt_printf("connect!\n");

        mosquitto_destroy(mqtt_ctx->mosq);
        mosquitto_lib_cleanup();
        sleep(1);
		return -4;
    }
    sleep(1);

    mqtt_printf ("mosquitto_connect_async call successful!\n");

	//打开无阻塞循环
#if 1
//	if(mosquitto_loop_forever(mqtt_ctx->mosq, -1, 1 ) != MOSQ_ERR_SUCCESS)
    if(mosquitto_loop_start(mqtt_ctx->mosq) != MOSQ_ERR_SUCCESS)
	{
		mqtt_printf("mosquitto loop error\n");
		sleep(1);
		return -5;
	}
	else	
	{
		mqtt_printf ("loop successful\n");
		return 0;
	}

#endif

#endif
}

void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
    /* Pring all log messages regardless of level. */
    mqtt_printf("log_callback: %s\n", str);
}


void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
    if(!result)
    {
        mqtt_printf ("connect_callback: Connected to server sucessfully!\n");
#if  0
        if( (rv = get_temperature(&payload)) < 0)
        {
            mqtt_printf("get_temperature failure!\n");
//          return ;
        }
		mqtt_printf ("get template successful:%f\n", payload);
#endif
    }

    else
    {
        mqtt_printf("connect_callback: Connect failed!\n");
        return;
    }
}

// 当断开连接时调用回调该函数
void on_disconnect(struct mosquitto *mosq, void *obj, int rc)
{
    if(0 == rc)
    {
        mqtt_printf("disconnect callback: disconnect sucessfully!\n");
        return ;
    }
    else
    {
        mqtt_printf("disconnect callback: disconnect failure!\n");
        return ;
    }
}

//发布成功时回调
void on_publish(struct mosquitto *mosq, void *obj, int reason_code)
{
        int rc;
      mqtt_printf("on_publish: %s\n", mosquitto_pulickack_string(reason_code));
        if(reason_code != 0)
        {
               mqtt_printf("publish callback: publish sucessfully!\n");
               return ;
        }
        mqtt_printf("publish callback: publish failure!\n");
}

// 当客户端收到消息时调用回调该函数
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{
        // 打印有效载荷
        mqtt_printf("message callback:%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}

// 当代理在响应订阅发送SUBACK时调用回调
void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
        int i;
        bool have_subscription = false;

        for(i=0; i<qos_count; i++){
                mqtt_printf("subscribe callback: %d:granted qos = %d\n", i, granted_qos[i]);
                if(granted_qos[i] <= 2){
                        have_subscription = true;
                }
        }
        if(have_subscription == false){
                mqtt_printf("Error: All subscriptions rejected.\n");
                mosquitto_disconnect(mosq);
        }
}



